<template>
  <div style="height: 100%">
    <div id="left">
      <InputGroup>
        <Input placeholder="用户手机号" size="small" v-model:value="queryParams.phone">
          <template #prefix>
            <PhoneOutlined />
          </template>
        </Input>
        <div style="display: flex">
          <DatePicker v-model:value="queryParams.date" />
          <a-button type="primary" @click="clickQuery"> Search </a-button>
        </div>
      </InputGroup>
      <Collapse>
        <CollapsePanel key="1" header="用户的当前套餐使用情况" :disable="false">
          <p>
            <strong>昵称：</strong>{{ curUser.nickname }}
            <strong>手机号：</strong>{{ curUser.phone }}
          </p>
          <ol>
            <li>当前已用国内流量：{{ usingStatus.usedDomesticData }} M，剩余 {{ curPackage.hasFreeDomesticData - usingStatus.usedDomesticData }} M</li>
            <li>当前已用国外流量：{{ usingStatus.usedOverseaData }} M，剩余 {{ curPackage.hasFreeOverseaData - usingStatus.usedOverseaData }} M</li>
            <li>当前已用国内语音拨打时间：{{ usingStatus.usedDomesticVoiceCall }} 分钟，剩余 {{ curPackage.hasFreeDomesticVoiceCall - usingStatus.usedDomesticVoiceCall }} 分钟</li>
            <li>当前已用国外语音拨打时间：{{ usingStatus.usedOverseaVoiceCall }} 分钟，剩余 {{ curPackage.hasFreeOverseaVoiceCall - usingStatus.usedOverseaVoiceCall }} 分钟</li>
          </ol>
        </CollapsePanel>
      </Collapse>
      <Table :columns="tableColumns" :dataSource="tableDataSource" :sortDirections="['descend', 'ascend']"/>
    </div>

    <div id="container"></div>

    <Drawer
      :title="chosenPackage.name"
      placement="right"
      :closable="false"
      v-model:visible="visible"
      :after-visible-change="afterVisibleChange"
    >
      <ul>
        <li>赠送国内流量 {{ chosenPackage.hasFreeDomesticData }} M</li>
        <li>套餐外国内流量 {{ chosenPackage.domesticDataExtraCharge }} 元/MB</li>
        <li>赠送国外流量 {{ chosenPackage.hasFreeOverseaData }} M</li>
        <li>套餐外国外流量 {{ chosenPackage.overseaDataExtraCharge }} 元/MB</li>
        <li>赠送国内通话 {{ chosenPackage.hasFreeDomesticVoiceCall }} 分钟</li>
        <li>超出后国内通话 {{ chosenPackage.domesticVoiceCallExtraCharge }} 元/分钟</li>
      </ul>
    </Drawer>
  </div>
</template>

<script lang="ts" setup>
  import { onMounted, reactive, Ref, ref } from 'vue';
  import { DatePicker, Drawer, Input, InputGroup, Table } from 'ant-design-vue';
  import { PhoneOutlined } from '@ant-design/icons-vue';
  import { Collapse, CollapsePanel } from 'ant-design-vue';
  import * as echarts from 'echarts/core';
  import {
    LegendComponent,
    LegendComponentOption,
    TitleComponent,
    TitleComponentOption,
    TooltipComponent,
    TooltipComponentOption,
  } from 'echarts/components';
  import { GraphChart, GraphSeriesOption } from 'echarts/charts';
  import { CanvasRenderer } from 'echarts/renderers';
  import { getRecommendPkg } from '/@/api/sys/recommend';
  import { MobilePackageDetail, UserSimple, UsingStatus } from '/@/api/sys/model/recommend';
  import { QueryFormParams, TableDataItem } from './model';
  import moment from 'moment';

  type EChartsOption = echarts.ComposeOption<
    TitleComponentOption | TooltipComponentOption | LegendComponentOption | GraphSeriesOption
  >;

  // 表格的表头数据
  const tableColumns = [
    {
      title: '套餐名称',
      dataIndex: 'name',
      key: 'name',
    },
    {
      title: '基础费用',
      dataIndex: 'baseCharge',
      key: 'baseCharge',
      sorter: (a: TableDataItem, b: TableDataItem) => a.baseCharge - b.baseCharge,
    },
    {
      title: '免费流量',
      dataIndex: 'freeDomesticData',
      key: 'freeDomesticData',
      sorter: (a: TableDataItem, b: TableDataItem) => a.freeDomesticData - b.freeDomesticData,
    },
    {
      title: '免费语音时间',
      dataIndex: 'freeDomesticVoiceCall',
      key: 'freeDomesticVoiceCall',
      sorter: (a: TableDataItem, b: TableDataItem) =>
        a.freeDomesticVoiceCall - b.freeDomesticVoiceCall,
    },
  ];

  const tableDataSource: TableDataItem[] = reactive([]);

  const visible = ref<boolean>(false); // 指示是否显示抽屉

  const afterVisibleChange = (bool: boolean) => {
    console.log('visible', bool);
  };

  const queryParams: QueryFormParams = reactive<QueryFormParams>({
    phone: '',
    date: moment(),
  });

  const chosenPackage: MobilePackageDetail = reactive({});

  const fillDrawerContent = (pkg: MobilePackageDetail) => {
    chosenPackage.name = pkg.name;
    chosenPackage.id = pkg.id;
    chosenPackage.baseCharge = pkg.baseCharge;
    chosenPackage.hasFreeDomesticData = pkg.hasFreeDomesticData;
    chosenPackage.hasFreeOverseaData = pkg.hasFreeOverseaData;
    chosenPackage.hasFreeDomesticMsg = pkg.hasFreeDomesticMsg;
    chosenPackage.hasFreeOverseaMsg = pkg.hasFreeOverseaMsg;
    chosenPackage.hasFreeDomesticVoiceCall = pkg.hasFreeDomesticVoiceCall;
    chosenPackage.hasFreeOverseaVoiceCall = pkg.hasFreeOverseaVoiceCall;
    chosenPackage.hasFreeDomesticVoiceRecv = pkg.hasFreeDomesticVoiceRecv;
    chosenPackage.hasFreeOverseaVoiceRecv = pkg.hasFreeOverseaVoiceRecv;
    chosenPackage.domesticDataExtraCharge = pkg.domesticDataExtraCharge;
    chosenPackage.overseaDataExtraCharge = pkg.overseaDataExtraCharge;
    chosenPackage.domesticMsgExtraCharge = pkg.domesticDataExtraCharge;
    chosenPackage.overseaMsgExtraCharge = pkg.overseaMsgExtraCharge;
    chosenPackage.domesticVoiceCallExtraCharge = pkg.domesticVoiceCallExtraCharge;
    chosenPackage.overseaVoiceCallExtraCharge = pkg.overseaVoiceCallExtraCharge;
    chosenPackage.domesticVoiceRecvExtraCharge = pkg.domesticVoiceRecvExtraCharge;
  };

  let myChart: echarts.ECharts;

  const initEchartsGraph = (nodes, links) => {
    let option: EChartsOption = {
      title: {
        text: '套餐推荐图谱',
      },
      tooltip: {},
      animationDurationUpdate: 1500,
      animationEasingUpdate: 'quinticInOut',
      series: [
        {
          type: 'graph',
          layout: 'circular',
          symbolSize: 50,
          roam: true,
          label: {
            show: true,
          },
          edgeSymbol: ['circle', 'arrow'],
          edgeSymbolSize: [4, 10],
          edgeLabel: {
            fontSize: 20,
          },
          categories: [
            { name: '用户', symbol: 'rect' },
            { name: '套餐', symbol: 'circle' },
          ],
          nodes: nodes,
          links: links,
          lineStyle: {
            opacity: 0.9,
            width: 2,
            curveness: 0,
          },
        },
      ],
    };
    myChart.setOption(option);

    // 注册用户双击节点的行为
    myChart.on('dblclick', function (params) {
      console.log(params);
      console.log(packagesDetail[params.dataIndex]);
      // 只要当用户所点击的是套餐的时候才显示抽屉
      if (params.data['category'] === 1) {
        fillDrawerContent(packagesDetail[params.dataIndex]);
        visible.value = true;
      }
    });
  };

  /**
   * 创建关系图的各节点
   * @param pkgs 各套餐数据
   */
  const convertPkgsToNodes = (pkgs: MobilePackageDetail[]) => {
    const graphNodes: any[] = [];
    pkgs.forEach((pkg) => {
      graphNodes.push({
        name: pkg.name,
        category: 1,
      });
    });
    return graphNodes;
  };

  /**
   * 创建关系图的各链接
   * @param pkgs 各套餐数据
   * @param userNode 用来表示用户的节点
   */
  const createLinks = (pkgs: MobilePackageDetail[], userNode) => {
    const graphLinks: any[] = [];
    pkgs.forEach((p) => {
      graphLinks.push({
        source: userNode.name,
        target: p.name,
      });
    });
    return graphLinks;
  };

  let userNode; // 用于表示用户的节点

  /**
   * 创建出用户的节点
   * @param user
   */
  const createUserNode = (user: UserSimple) => {
    return {
      name: user.nickname,
      category: 0,
    };
  };

  /**
   * 创建表格中的数据
   * @param pkgs 所推荐的所有套餐
   */
  function createTableDataSources(pkgs: MobilePackageDetail[]) {
    tableDataSource.length = 0;
    pkgs.forEach((p) => {
      tableDataSource.push({
        key: p.id,
        name: p.name,
        baseCharge: p.baseCharge,
        freeDomesticData: p.hasFreeDomesticData,
        freeDomesticVoiceCall: p.hasFreeDomesticVoiceCall,
      });
    });
  }

  let packagesDetail: MobilePackageDetail[] = reactive([]); // 通过请求后端得到的推荐的各套餐数据
  const curUser: Ref<UserSimple> = ref({
    userId: '',
    phone: '',
    nickname: '',
  });
  const usingStatus: Ref<UsingStatus> = ref({
    phone: '',
    recordTime: '',
    pkgId: '',
    usedDomesticData: 0,
    usedOverseaData: 0,
    usedDomesticMsg: 0,
    usedOverseaMsg: 0,
    usedDomesticVoiceCall: 0,
    usedOverseaVoiceCall: 0,
    usedDomesticVoiceRecv: 0,
    usedOverseaVoiceRecv: 0,
    appPreference1: '',
    appPreference2: '',
    appPreference3: '',
  });
  const curPackage: Ref<MobilePackageDetail> = ref({
    id: '',
    name: '',
    generation: 0,
    baseCharge: 0,
    hasFreeDomesticData: 0,
    hasFreeOverseaData: 0,
    domesticDataExtraCharge: 0,
    overseaDataExtraCharge: 0,
    hasFreeDomesticVoiceCall: 0,
    hasFreeOverseaVoiceCall: 0,
    domesticVoiceCallExtraCharge: 0,
    overseaVoiceCallExtraCharge: 0,
    hasFreeDomesticVoiceRecv: 0,
    hasFreeOverseaVoiceRecv: 0,
    domesticVoiceRecvExtraCharge: 0,
    overseaVoiceRecvExtraCharge: 0,
    hasFreeDomesticMsg: 0,
    hasFreeOverseaMsg: 0,
    domesticMsgExtraCharge: 0,
    overseaMsgExtraCharge: 0,
  });

  // 当用户点击搜索时触发的行为：通过请求后端获得推荐的套餐数据，得到数据后生成关系图
  function clickQuery() {
    const recommendParams = {
      phone: queryParams.phone,
      date: queryParams.date.format('YYYY-MM-DD'),
    };
    console.log('params:');
    console.log(recommendParams);
    getRecommendPkg(recommendParams).then((recommendResult) => {
      const packages = recommendResult.packages;
      packagesDetail = packages;
      curUser.value = recommendResult.user;
      usingStatus.value = recommendResult.usingStatus;
      curPackage.value = recommendResult.curPackage;
      const nodes = convertPkgsToNodes(packages);
      userNode = createUserNode(recommendResult.user);
      const links = createLinks(packages, userNode);
      createTableDataSources(packages);
      console.log(tableDataSource);
      nodes.push(userNode);
      console.log(packages);
      console.log(nodes);
      initEchartsGraph(nodes, links); // 生成关系图
    });
  }

  onMounted(() => {
    echarts.use([TitleComponent, TooltipComponent, LegendComponent, GraphChart, CanvasRenderer]);
    const chartDom = document.getElementById('container')!;
    myChart = echarts.init(chartDom);
  });
</script>

<style scoped>
  #left {
    line-height: 30px;
    background-color: #eeeeee;
    height: 100%;
    width: 38%;
    float: left;
    padding: 5px;
  }
  #container {
    width: 62%;
    height: 100%;
    float: left;
    padding: 10px;
  }
</style>
